package com.ctim.web.index;

import com.ctfin.oss.alibaba.aliyun.oss.properties.OSSClientProperties;
import com.ctim.common.exception.EnumPcsService;
import com.ctim.common.pcs.PcsResult;
import com.ctim.common.tool.json.JSONUtil;
import com.ctim.dao.user.DemoDao;
import com.ctim.model.user.User;
import com.ctim.web.common.BaseController;
import com.ctim.web.util.VerifyCodeUtils;
import com.ctim.web.util.oss.OSSMutiUploadFile;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Author: Wangwei
 * Date: 2016/8/18
 * Desc:首页
 */
@RestController
@RequestMapping("/rest/index")
public class IndexController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Autowired
    private SecurityManager securityManager;

    @Value("${spring.profiles.active}")
    private String profile;

    @Autowired
    private DemoDao demoDao;

    @Value("${oss.key.attachment_prefix}")
    private String KEY_PREFIX;


    @RequestMapping(value = "/",method = RequestMethod.GET)
    public PcsResult index() {// 第一次调用登陆接口是，会走该接口
        return newResult();
    }

    @RequestMapping(value = "/unauth",method = RequestMethod.GET)
    public PcsResult unauth() {
        return newResult().setData("1");
    }

    /**
     * 验证码
     */
    @RequestMapping(value = "/captcha",method = RequestMethod.GET)
    public void Captcha(HttpServletResponse response,HttpServletRequest request) throws IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        //生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        //存入会话session
        HttpSession session = request.getSession(true);
        //删除以前的
        session.removeAttribute("verCode");
        session.setAttribute("verCode", verifyCode.toLowerCase());
        //生成图片
        int w = 120, h = 42;
        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
    }


    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public PcsResult login() {
        PcsResult result = new PcsResult();
        result.setCode(EnumPcsService.ACCESS_TOKEN_INVALID.getCode()).setMessage(EnumPcsService.ACCESS_TOKEN_INVALID.getDesc());
        return result;
    }

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    // 此方法不处理登录成功,由shiro进行处理.
    public PcsResult login(HttpServletRequest request, @RequestParam("username") String username,
                           @RequestParam("password") String password, @RequestParam("verify") String verify) throws Exception {
        PcsResult result = new PcsResult();
        String code = String.valueOf(request.getSession().getAttribute("verCode"));
        if (profile.equals("prod")) {
            if (StringUtils.isEmpty(verify) || (code!=null && !code.equals(verify.toLowerCase()))) {
                result.setCode(EnumPcsService.BUSINESS_USER_VERIFYCODE_ERROR.getCode());
                result.setMessage(EnumPcsService.BUSINESS_USER_VERIFYCODE_ERROR.getDesc());
                return result;
            }
        }


        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch (AuthenticationException exception) {
            logger.info("IndexController.login() fail: {}", ExceptionUtils.getMessage(exception));
            // 登录失败从request中获取shiro处理的异常信息。
            // shiroLoginFailure:就是shiro异常类的全类名.
            EnumPcsService msg = EnumPcsService.BUSINESS_DATA_NONE;
            if (exception != null) {
                if (exception instanceof UnknownAccountException) {// 账号不存在
                    msg = EnumPcsService.BUSINESS_USER_NONE;
                } else if (exception instanceof IncorrectCredentialsException) {// 密码不正确
                    msg = EnumPcsService.BUSINESS_USER_PASSWORD_ERROR;
                } else if (exception instanceof ExcessiveAttemptsException) {// 登录失败多次
                    msg = EnumPcsService.BUSINESS_USER_LOGIN_ERROR;
                } else if ("kaptchaValidateFailed".equals(exception)) {// 验证码错误
                    msg = EnumPcsService.BUSINESS_USER_VERIFYCODE_ERROR;
                }
            }
            result.setCode(msg.getCode()).setMessage(msg.getDesc());
        }
        User user = (User) subject.getPrincipal();
        result.setData(JSONUtil.filterIncludeProperties(user, User.class,
                "userId", "username", "email", "phone", "menuTree", "permissions","tid", "manager", "defaultIndexUrl"));
        return result;
    }

    @RequestMapping(value = "/logout",method = RequestMethod.POST)
    public PcsResult logout() {
        SecurityUtils.getSubject().logout();
        return newResult();
    }

    @RequestMapping(value = "/publish",method = RequestMethod.POST)
    public PcsResult publish(@RequestParam String content) {
        demoDao.insert(content);
        return newResult();
    }

    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public PcsResult add(@RequestParam("remark") String remark, @RequestParam("file") MultipartFile[] files) throws Exception {
        // 获取上传的文件
        for(MultipartFile multipartFile : files){
            // 对文件进处理
            String fileName = multipartFile.getOriginalFilename();
            String key = KEY_PREFIX + System.currentTimeMillis() + "_" + fileName;
            BufferedInputStream bf = new BufferedInputStream(multipartFile.getInputStream());// 缓冲区100K
            OSSMutiUploadFile ossMutiUploader = new OSSMutiUploadFile(bf, OSSClientProperties.bucketName, key);
            ossMutiUploader.uploadFile();
            System.out.println("filename:" + fileName);
        }
        return newResult();
    }

}
